﻿using System;
using DataModels.Common;
using DataModels.Models;
using GenericTools.ReportProcessing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Linq;
using DataModels.Models.Context;

namespace GenericTools.Tests.ReportProcessing
{
    [TestClass]
    public class RegistrationInfoTest
    {
        [ClassInitialize()]
        public static void MyClassInitialize(TestContext testContext)
        {
            AppConfiguration.AccessMethod = DataModels.Enumerations.DataAccessMethod.DIRECT_ACCESS;
            AppConfiguration.DBConnectionString = @"Data Source=(local)\SQLEXPRESS;Initial Catalog=IQSMS_TestDB.Development;Integrated Security=True";
        }

        [TestMethod]
        public void Reporting_Text_Has_No_Error()
        {
            string registrationText = "Moses Kehengu eng 04010100";
            string senderNumber = "+255713468325"; 
            bool userExisted;
            RegistrationInfo.RemoveUserRegistration(senderNumber, out userExisted);

            var target = new RegistrationInfo(senderNumber, registrationText);
            Assert.IsFalse(target.HasError, target.ErrorText);
        }

        [TestMethod]
        public void Username_Is_Retrieved_Properly()
        {
            string registrationText = "Moses Kehengu eng 04010100";
            string senderNumber = "+255713468325";

            var target = new RegistrationInfo(senderNumber, registrationText);

            string sExpected = "Moses Kehengu";
            string sActual = target.RegisteredFullname;
            Assert.AreEqual(sExpected, sActual, target.ErrorText);
        }

        [TestMethod]
        public void Sender_Number_Is_Retrieved_Properly()
        {
            string registrationText = "Moses Kehengu eng 04010100";
            string senderNumber = "+255713468325";

            var target = new RegistrationInfo(senderNumber, registrationText);

            string sExpected = senderNumber;
            string sActual = target.SenderNum;
            Assert.AreEqual(sExpected, sActual, target.ErrorText);
        }

        [TestMethod]
        public void Facility_Code_Is_Retrieved_Properly()
        {
            string registrationText = "Moses Kehengu eng 04010100";
            string senderNumber = "+255713468325";
            bool userExisted;
            RegistrationInfo.RemoveUserRegistration(senderNumber, out userExisted);

            var target = new RegistrationInfo(senderNumber, registrationText);

            string sExpected = "04010100";
            string sActual = target.FacilityCode;
            Assert.AreEqual(sExpected, sActual, target.ErrorText);
        }

        [TestMethod]
        public void Username_Is_Saved_Properly()
        {
            string registrationText = "Moses Kehengu eng 04010100";
            string senderNumber = "+255713468325";

            var target = new RegistrationInfo(senderNumber, registrationText);
            target.RemoveUserRegistration();

            bool bActual = target.Register();
            bool bExpected = true;
            Assert.AreEqual(bExpected, bActual, target.ErrorText);

            using (var db = new IQSMS_TestDBContext())
            {
                var result = from u in db.ApprovedSMSCells
                             where u.CellNum == senderNumber
                             select u;

                var users = result.ToList();
                Assert.AreNotEqual(0, "Record is not saved into the database");
                Assert.AreEqual(1, users.Count, "More than one user is having the same phone number");

                var userInfo = users[0];
                string sExpected = "Moses Kehengu";
                string sActual = userInfo.Name;
                Assert.AreEqual(sExpected, sActual, "Record 'Name' is not saved properly");
            }
        }

        [TestMethod]
        public void Facility_Code_Is_Saved_Properly()
        {
            string registrationText = "Moses Kehengu eng 04010100";
            string senderNumber = "+255713468325"; 
            bool userExisted;
            RegistrationInfo.RemoveUserRegistration(senderNumber, out userExisted);

            var target = new RegistrationInfo(senderNumber, registrationText);
            bool bActual = target.Register();
            bool bExpected = true;
            Assert.AreEqual(bExpected, bActual, target.ErrorText);
            
            var cExpected = RegistrationInfo.RegistrationError.NO_ERROR;
            Assert.AreEqual(cExpected, target.Error, target.ErrorText);

            using (var db = new IQSMS_TestDBContext())
            {
                var result = from u in db.ApprovedSMSCells
                             where u.CellNum == senderNumber
                             select u;

                var users = result.ToList();
                Assert.AreEqual(1, users.Count, "More than one user is having the same phone number");

                var userInfo = users[0];
                Assert.IsNotNull(userInfo, "Record is not saved into the database");

                string sExpected = "04010100";
                string sActual = userInfo.FacCode;
                Assert.AreEqual(sExpected, sActual, "Record 'Name' is not saved properly");
            }
        }

        [TestMethod]
        public void RegistrationCheck_Is_Working()
        {
            var guid = Guid.NewGuid();
            string phoneNumber = guid.ToString();

            bool bActual = RegistrationInfo.IsUserRegistered(phoneNumber);
            Assert.IsFalse(bActual, "User is not registered but reported registered");
        }

        [TestMethod]
        public void User_Removal_Is_Working()
        {
            var guid = Guid.NewGuid();
            string phoneNumber = guid.ToString();
            string registrationText = "Moses Kehengu eng 04010100";

            var target = new RegistrationInfo(phoneNumber, registrationText);
            bool bActual = target.Register();
            Assert.IsTrue(bActual, target.ErrorText);

            bActual = RegistrationInfo.IsUserRegistered(phoneNumber);
            Assert.IsTrue(bActual, "User is registered but reported not registered");

            bool userExisted;
            bool removed = RegistrationInfo.RemoveUserRegistration(phoneNumber, out userExisted);

            Assert.IsTrue(userExisted, "User existed but reported didn't exist");
            Assert.IsTrue(removed, "User not removed");

            bActual = RegistrationInfo.IsUserRegistered(phoneNumber);
            Assert.IsFalse(bActual, "User is still not removed from the system");
        }
    }
}
